package com.phoenix.shuaidatabase.utils;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;

public class LeakyBucketRateLimiter implements ShuaiRateLimiter{

    ConcurrentHashMap<String,LeakyBucket> resources;

    public LeakyBucketRateLimiter(ArrayList<String> resourceNames,int n) {
        this.resources = new ConcurrentHashMap<>();
        for(String resource : resourceNames) {
            this.resources.put(resource,new LeakyBucket(n));
        }
    }

    @Override
    public boolean tryAcquire(String resource) {
        return resources.get(resource).isAllowed();
    }

    private static class LeakyBucket {
        private final int limit; //桶的容量
        private final int rate; //漏出的速率
        private int leftWater; //剩余水量
        private long lastTime; //上次注水时间

        public LeakyBucket(int n) {
            this.limit = n;
            this.rate = n;
            this.leftWater = 0;
            this.lastTime = System.currentTimeMillis();
        }

        public synchronized boolean isAllowed() {
            long now = System.currentTimeMillis();
            long gap = (now - lastTime) / 1000;
            this.leftWater = (int)Math.max(0,leftWater - gap * rate);
            if(leftWater < limit) {
                leftWater ++;
                lastTime = now;
                return true;
            }
            return false;
        }

    }
}
